﻿using HPSocket;
using HPSocket.Tcp;
using IntelligentGateway.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Org.BouncyCastle.Math.EC.ECCurve;

namespace IntelligentGateway.Services
{
    public class IGTCPServer
    {
        TcpServer _tcpServer;
        public IGTCPServer(string IPAddress, ushort Port)
        {
            _tcpServer = new TcpServer();
            _tcpServer.Port = Port;
            _tcpServer.Address = IPAddress;
            _tcpServer.OnReceive += _tcpServer_OnReceive;
            _tcpServer.OnAccept += _tcpServer_OnAccept;
            _tcpServer.OnClose += _tcpServer_OnClose;
            _tcpServer.OnSend += _tcpServer_OnSend; 
        }
        public List<IntPtr> GetAllIntPtrs()
        {
            return _tcpServer.GetAllConnectionIds();
        }
        public string GetIpAddress(IntPtr intPtr)
        {
            ushort port = 0;
            string ipAddress = string.Empty;
            _tcpServer.GetRemoteAddress(intPtr,out ipAddress,out port);
            return ipAddress;
        }
        private HPSocket.HandleResult _tcpServer_OnAccept(HPSocket.IServer sender, IntPtr connId, IntPtr client)
        {
            string ipAddress = string.Empty;
            ushort port = 0;
            _tcpServer.GetRemoteAddress(client, out ipAddress, out port);
            IntelligentGatewayServices.sendDevStateUpdate(ipAddress, 1);
#if DEBUG           
            Log.Debug($"{ipAddress}:{port}connected!");
#endif
            return HPSocket.HandleResult.Ok;
        }

        private HPSocket.HandleResult _tcpServer_OnSend(HPSocket.IServer sender, IntPtr connId, byte[] data)
        {
            return HPSocket.HandleResult.Ok;
        }

        private HPSocket.HandleResult _tcpServer_OnClose(HPSocket.IServer sender, IntPtr connId, HPSocket.SocketOperation socketOperation, int errorCode)
        {
            string ipAddress = string.Empty;
            ushort port = 0;
            _tcpServer.GetRemoteAddress(connId, out ipAddress, out port);
            IntelligentGatewayServices.sendDevStateUpdate(ipAddress, 0);
#if DEBUG           
            Log.Debug($"{ipAddress}:{port} close:{socketOperation}:errcode:{errorCode}");
#endif
            return HPSocket.HandleResult.Ok;
        }

        private HPSocket.HandleResult _tcpServer_OnReceive(HPSocket.IServer sender, IntPtr connId, byte[] data)
        {
            if (data.Length <= 0) return HPSocket.HandleResult.Ok;
            if (data[0] != 0xA7) return HPSocket.HandleResult.Ok;
            if (data[3] == 0x03)
            {
                IGTCPServerMessageProcess.MessageUnPacket(data);
            }
#if DEBUG
            string ipAddress = string.Empty;
            ushort port = 0;
            _tcpServer.GetRemoteAddress(connId, out ipAddress, out port);
            Log.Debug($"{ipAddress}:{port} ReceviceData:{UTools.ToHexs(data)}");
#endif
            return HPSocket.HandleResult.Ok;
        }
        public bool SendData(string Address,byte[] data)
        {
            IntPtr intPtr = IntPtr.Zero;
            List<IntPtr> lst = _tcpServer.GetAllConnectionIds();
#if DEBUG
            string ipAddress = string.Empty;
            ushort iport = 0;
#endif
            foreach (var item in lst)            
            {
                string address = string.Empty;
                ushort port = 0;
                this._tcpServer.GetRemoteAddress(item, out address, out port);
                if(address.Equals(Address))
                {
                    intPtr = item;
#if DEBUG
                    ipAddress = address;
                    iport = port;
#endif
                    break;
                }
            };
            if (intPtr != IntPtr.Zero)
            {
#if DEBUG
                
                Log.Debug($"senddatato:{ipAddress}:{iport}:{UTools.ToHexs(data)}");
#endif
                return _tcpServer.Send(intPtr, data, data.Length);
            }
            else return false;
        }
        public bool SendData(IntPtr intPtr, byte[] data)
        {
#if DEBUG

            Log.Debug($"senddatato intptr:{GlobalVariables.IGTCPServer.GetIpAddress(intPtr)}:{UTools.ToHexs(data)}");
#endif
            return _tcpServer.Send(intPtr, data, data.Length);
        }
        public bool Start()
        {
            if (!_tcpServer.Start())
            {
                return false;
            }
            else return true;
        }
    }
}
